函數在程式中是很重要的一部分,用來完成特定任務、並且可以重複使用的程式碼區塊。基本上程式就是一系列的函數組成來完成一個比較複雜的任務。
其實前面一直使用的println()就是Kotlin標準庫準備好的函數。
我們也可以自訂函數,比如:需不需要傳入參數,還有完成任務後要不要返回資料供其他地方使用。
以這個add function為例,說明函數的組成:
private fun add(a :Int, b:Int):Int{
return a+b
}
private
: 可見性修飾符,沒有特別註明的話,是預設public。fun
: 函數宣告關鍵字add
: 函數名,採小駝峰命名,能準確表達這函數的任務為佳。()
:指定參數的地方,多個參數時,以逗點隔開,參數必須標明資料類別。呼叫此function時就必須依據需求傳入資料雷行符合的參數。:Int
: 返回值類型,很多函數都會返回值給呼叫者,如沒有寫明的話會是「:Unit」(此時return可省略不寫),如下例沒有標明返回類型:
private fun foo(a:Int, b:Int){
/*一些執行的任務*/
return Unit//可選擇寫或不寫,一般都會省略
}
{}
: 函數本體,上面介紹的合起來private fun add(a :Int, b:Int):Int
是函數標頭。大括號{}
為函數本體,是執行任務的地方,若需要返回資料的話,還會有相關語句指定回傳哪一些資料。在函數本體{}中,變數的宣告、定義都在這裡完成,這個變數就只活在這個函數本體{}中,出了這個花括號,其他地方並不能辨識這個變數。
以下面這個函數foo舉例,定義一個變數strLength,在foo function以外的地方是無法使用的:
像上例strLenght這類宣告在function裡面的變數就叫做區域變數,因為它只存在函數本體內,這函數執行完後就不復存在,所以作用域可以理解成區域變數的生命週期。對於函數的參數來說也是如此,一旦執行完畢,參數也就消失了。
豆知識 :常看到foo是什麼意思? 如果常常爬程式類的文章,常常會看見foo、bar...等詞用來當變數名或函數名,說法很多,但總結就是名稱不影響說明,所以懶得想變數或函數名字,通用的一個舉例用名稱。地位相當於課堂中的小明吧,我想。有興趣了解:Foobar維基百科
宣告完函數、定義了他的任務並不會使函數去執行。我們需要呼叫他,就像少年漫畫,主角使出招式前必須大聲喊出招式名一樣,而反派也都會乖乖聽完(??)。我想要請不會喊出招式的鬼滅之刃的鬼妹妹Nezuko來示範:
Nezuko如大家所知,具備了戰鬥功能,並且會為了保護哥哥和人類與鬼戰鬥,就假設當被鬼攻擊的時候,Nezuko會依據剩餘血量(0~100)的多少來做出一些反應,沒有鬼攻擊的時候,就會躲回箱子睡覺恢復體力,血量hp以Int來表示,而是否遭受鬼攻擊就以Boolean值來表示:
fun fight(hp: Int, demonIsAttacking: Boolean): String {
val fightStatus = when (hp) {
in 101..Int.MAX_VALUE -> "禰豆子升級~~"
in 70..100 -> if (demonIsAttacking) "禰豆子一般戰鬥" else "禰豆子躲箱子睡覺"
in 40..69 -> if (demonIsAttacking) "禰豆子暴怒 再生速度upup" else "禰豆子躲箱子睡覺"
in 10..39 -> if (demonIsAttacking) "禰豆子使出血鬼術「爆血」機率提升30%" else "禰豆子躲箱子睡覺"
else -> if (demonIsAttacking) "禰豆子失去意識" else "禰豆子躲箱子睡覺"
}
return "$fightStatus (hp:$hp, demon is Attacking : $demonIsAttacking)"
}
定義好戰鬥功能後,就要使用他囉。
在需要戰鬥技能的地方呼叫fight function,並傳入引數(nezukoHp、demonIsAttacking)讓function可以完成任務,把fight返回的字串存入變數nezukoStatus並印出看看,試著更改 nezukoHp 和 demonIsAttacking 的值,看看禰豆子如何戰鬥吧。
fun main() {
var nezukoHp = 100
var demonIsAttacking = true
val nezukoStatus = fight(nezukoHp, demonIsAttacking) //函數也可以儲存在變數裡
println(nezukoStatus)
//或是: println(fight(nezukoHp, demonIsAttacking))
}
函數的定義表明需要兩個參數(paramenter)。呼叫時我們必須在括號()中傳入參數要求的資料,這種輸入資料名叫引數(arguement),為函數提供輸入資料叫傳入引數。
(術語說明:技術上來說,參數是函數需要的東西,而引數是由函數呼叫者傳入,以滿足函數參數的要求。) 引自:Kotlin權威2.0
我們可以預先為函數參數預設初始值引數,如預設每次禰豆子都是滿血戰鬥:
fun fight(hp: Int = 100, demonIsAttacking: Boolean): String {...}
呼叫時,若沒有特別指定hp值,預設就是100,那還需要傳入其他引數怎麼辦?直接指定參數名就好囉:
fight(demonIsAttacking = true) //hp =100,demonIsAttacking = true
當然,全部參數都可以預設引數,呼叫時便不需要輸入引數。需要改變其中某些引數時,在呼叫時,指名輸入新的值就可以囉。
這就是函數基本的用法了,明天見。